home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / tr.c < prev    next >
C/C++ Source or Header  |  1990-07-15  |  3KB  |  158 lines

  1. /* tr - translate characters        Author: Michiel Huisjes */
  2. /* Usage: tr [-cds] [string1 [string2]]
  3.  *    c: take complement of string1
  4.  *    d: delete input characters coded string1
  5.  *    s: squeeze multiple output characters of string2 into one character
  6.  */
  7.  
  8. #define BUFFER_SIZE    1024
  9. #define ASCII        0377
  10.  
  11. typedef char BOOL;
  12. #define TRUE    1
  13. #define FALSE    0
  14.  
  15. #define NIL_PTR        ((char *) 0)
  16.  
  17. BOOL com_fl, del_fl, sq_fl;
  18.  
  19. unsigned char output[BUFFER_SIZE], input[BUFFER_SIZE];
  20. unsigned char vector[ASCII + 1];
  21. BOOL invec[ASCII + 1], outvec[ASCII + 1];
  22.  
  23. short in_index, out_index;
  24.  
  25. main(argc, argv)
  26. int argc;
  27. char *argv[];
  28. {
  29.   register unsigned char *ptr;
  30.   int index = 1;
  31.   short i;
  32.  
  33.   if (argc > 1 && argv[index][0] == '-') {
  34.     for (ptr = (unsigned char *) &argv[index][1]; *ptr; ptr++) {
  35.         switch (*ptr) {
  36.             case 'c':    com_fl = TRUE;    break;
  37.             case 'd':    del_fl = TRUE;    break;
  38.             case 's':    sq_fl = TRUE;    break;
  39.             default:
  40.             write(2,"Usage: tr [-cds] [string1 [string2]].\n", 38);
  41.             exit(1);
  42.         }
  43.     }
  44.     index++;
  45.   }
  46.   for (i = 0; i <= ASCII; i++) {
  47.     vector[i] = i;
  48.     invec[i] = outvec[i] = FALSE;
  49.   }
  50.  
  51.   if (argv[index] != NIL_PTR) {
  52.     expand(argv[index++], input);
  53.     if (com_fl) complement(input);
  54.     if (argv[index] != NIL_PTR) expand(argv[index], output);
  55.     if (argv[index] != NIL_PTR) map(input, output);
  56.     for (ptr = input; *ptr; ptr++) invec[*ptr] = TRUE;
  57.     for (ptr = output; *ptr; ptr++) outvec[*ptr] = TRUE;
  58.   }
  59.   convert();
  60. }
  61.  
  62. convert()
  63. {
  64.   short read_chars = 0;
  65.   short c, coded;
  66.   short last = -1;
  67.  
  68.   for (;;) {
  69.     if (in_index == read_chars) {
  70.         if ((read_chars = read(0, input, BUFFER_SIZE)) <= 0) {
  71.             if (write(1, output, out_index) != out_index)
  72.                 write(2, "Bad write\n", 10);
  73.             exit(0);
  74.         }
  75.         in_index = 0;
  76.     }
  77.     c = input[in_index++];
  78.     coded = vector[c];
  79.     if (del_fl && invec[c]) continue;
  80.     if (sq_fl && last == coded && outvec[coded]) continue;
  81.     output[out_index++] = last = coded;
  82.     if (out_index == BUFFER_SIZE) {
  83.         if (write(1, output, out_index) != out_index) {
  84.             write(2, "Bad write\n", 10);
  85.             exit(1);
  86.         }
  87.         out_index = 0;
  88.     }
  89.   }
  90.  
  91.   /* NOTREACHED */
  92. }
  93.  
  94. map(string1, string2)
  95. register unsigned char *string1, *string2;
  96. {
  97.   unsigned char last;
  98.  
  99.   while (*string1) {
  100.     if (*string2 == '\0')
  101.         vector[*string1] = last;
  102.     else
  103.         vector[*string1] = last = *string2++;
  104.     string1++;
  105.   }
  106. }
  107.  
  108. expand(arg, buffer)
  109. register char *arg;
  110. register unsigned char *buffer;
  111. {
  112.   int i, ac;
  113.  
  114.   while (*arg) {
  115.     if (*arg == '\\') {
  116.         arg++;
  117.         i = ac = 0;
  118.         if (*arg >= '0' && *arg <= '7') {
  119.             do {
  120.                 ac = (ac << 3) + *arg++ - '0';
  121.                 i++;
  122.             } while (i < 4 && *arg >= '0' && *arg <= '7');
  123.             *buffer++ = ac;
  124.         } else if (*arg != '\0')
  125.             *buffer++ = *arg++;
  126.     } else if (*arg == '[') {
  127.         arg++;
  128.         i = *arg++;
  129.         if (*arg++ != '-') {
  130.             *buffer++ = '[';
  131.             arg -= 2;
  132.             continue;
  133.         }
  134.         ac = *arg++;
  135.         while (i <= ac) *buffer++ = i++;
  136.         arg++;        /* Skip ']' */
  137.     } else
  138.         *buffer++ = *arg++;
  139.   }
  140. }
  141.  
  142. complement(buffer)
  143. unsigned char *buffer;
  144. {
  145.   register unsigned char *ptr;
  146.   register short i, index;
  147.   unsigned char conv[ASCII + 2];
  148.  
  149.   index = 0;
  150.   for (i = 1; i <= ASCII; i++) {
  151.     for (ptr = buffer; *ptr; ptr++)
  152.         if (*ptr == i) break;
  153.     if (*ptr == '\0') conv[index++] = i & ASCII;
  154.   }
  155.   conv[index] = '\0';
  156.   strcpy(buffer, conv);
  157. }
  158.